GSP-005
Hello Kubernetes
2017년 10월 19일 목요일
오전 9:45
링크: https://google.qwiklabs.com/focuses/7011
참고 유튜브: https://goo.gl/3ezwCV
 
당신이 개발한
코드를 Kubernetes 위에 복제해서 돌려보자
그런데 Kubernetes는 Google Container Engine 위에서
돌거다 
- 우리가 사용할 코드는 Hello World.js 앱이다 
 
아래 다이어그램이
전체 조망도이다. 
두고두고 살펴보자
* node = VM 한대
라고 생각하자 

 
- 오픈소스 프로젝트이다. www.kubernetes.io 
- 다양한 환경에서 동작한다
- laptop에서 multi-node clusters 까지
- public clouds에서 on-premise deployment 까지
- virtual machine 에서 bare metal (http://www.ciokorea.com/news/35402)
까지 
 
- 매니지드 환경을 사용해서
설치 등등은 바로 넘어가는 거다
- 매니지드 환경은 Google Container Engine 을 사용할거다
- 이것은 Compute Engine 위에 Google-hosted version의 Kubernetes 가 설치되어 있다
 
1) Node.js 서버
만들고
- server.js 만들고
- 서버 돌려본다음 종료
2) Docker Container image 만들고
- Dockerfile 만들고 (from 은 Cloud 의
docker hub 에서 가져온다?)
- 빌드하고 런하고 종료한다
- 이미지를 registry 에 push
3) Container cluster 만들고
- 웹콘솔에서 만들어봄
4) Kubernetes pod를 만들고
5) 나의 서비스를 scale up!
 
 
 
Google Cloud Shell 에서 server.js 파일을 다음과 같이 만들자
| 
   var http = require('http'); var handleRequest = function(request, response) {   response.writeHead(200);   response.end("Hello World!"); } var www = http.createServer(handleRequest);  | 
  
      | 
 
 
그리고 서버를
실행시키자 
- preview on port 8080 을 선택하면 볼 수 있다. 
| 
   node server.js  | 
  
      | 
 
 
Cloud Shell 에서 Ctrl-c 를 눌러서 서버 중지 
 
 
 
1) Dockerfile 은
우리가 만들 Docker image 의 설계도랄 수 있겠다. 
- 나중에 이렇게 만들어줘! 하고 주면 되는거다. 
2) Docker Container Image는 기존의 image 에서 확장이 가능하다. 
- node image를
가져와서
- 그 위에 우리의 server.js 만 덧붙여 올릴거다. 
 
Dockerfile 을 아래와 같이 만들자
  
  | 
  
   1. 기존에 GCP의
  Docker hub 에 있는 node:6.9.2 라는 도커이미지를 2. 8080 포트를 expose 한
  상태에서 3. server.js 를 복사해 붙이겠다. 점(.)은 현재 디렉토리를 의미하는 것 같다.  4. 그리고 node.js 서버를
  동작시키는 명령을 실행하라 - node server.js  | 
 
 
 
- PROJECT_ID 에는
진짜 내 프로젝트 아이디를 넣어야겠지?
- 도커이미지의 이름은
hello-node:v1 버전 1이라는 의미구만
- gcr.io 도 중요하다. 
- Google Container Registry 라는 도커 이미지를 넣어두는 공간
- Google Cloud Storage 에서 gs:// 라고
prefix 해주던 것과 유사한듯
| 
   질문! 여기서 gcr.io로 시작하는 것은 무얼 의미하는가?  us.gcr.io 라면 Registry 위치가 미국, 없으면 디폴트로 미국인듯 유럽이나
  아시아로 선택할 수도 있나보다 Registry 라면 나중에 push를 또하는건 뭐지?  PROJECT_ID 부분은
  옵션으로 보인다. 아무 이름이나 가능한듯 아무래도
  프로젝트 아이디를 넣으면 낸중에 알아보기 편할듯 마지막으로 -t 는 tag,
  점(.)은 Dockerfile의 위치를 의미한다
    | 
 
| 
   docker build -t gcr.io/PROJECT_ID/hello-node:v1 .ㄷ  | 
  
      | 
 
 
빌드되면 난수들이
나올 것이다. 그러면 완성
- Dockerfile 내용이
순서대로 실행되는게 보인다
- 중간 임시 파일들이
생성되고 삭제된다 
![shed-zephyr-17æ21 docker bui Id 
Sending bui Id context to C:ocker daemon Bg. CGk8 
step 1/4 : node:a.g.2 
a.g.2: FL] Il ing from library/node 
-t gcr. io/pol ished-zephyr-1 7Eæl/hel 0-node 
753æ2cd7æa: 
871 asa3b7æs: 
01 1 
I f04fe713flb: 
Pull complete 
Pull complete 
Pull complete 
Pull complete 
Pull complete 
Pull complete 
Pull complete 
Digest: lg40f44S&e4bd33fbdc34deg4a5e04.3 
Status: Downloaded newer image for node :a.g.2 
faaadb4aafgb 
step 2/4 : 
Running in 
IZ74bdaceaeO 
Removing intermediate container 
Step 3/4 : CDP/ server. js 
Remov ing intermed iate container SEEccbBbad51 
Step 4/4 : node server. js 
Running in c3b7æaseb73 
f4ScSlafeæs 
Remov ing intermediate container c.i7.3g&b7.3 
Successfully built f4&51afeBE 
Successfully tagged gcr io/pol i shed-zephyr-17æ21 'hel lo-node:vl](GSP-005%20Hello%20Kubernetes.files/image004.jpg)
 
이제는 run 
-d, --detach=false 라고 하여 Detached, daemon 모드라고 하며 컨테이너가 백그라운드로 실행됨
-p, --pubilsh=[] 라고 하여 <호스트포트>:<컨테이너포트> 를 의미한다 
![]()
 
이 자체로
도커 이미지가 Running !
![]()
 
결과를 보는
세 가지 방법
1) Shell 의 Preview on port 8080 선택

2) curl 또는 wget 사용
- culr http://localhost:8080
- 결과는 
![]()
 
1) 그냥 날로 node.js 서버를 실행시키거나 
2) 도커 이미지로 실행시키는
방법을 배웠다. 
 
1) PROJECT_ID를
안쓰고 그냥 아무 이름이나 써봤다
- 만들어지긴
하는데 나중에 push 할때 안된다. 
- 아마도 프로젝트 하위로 container registry 가 있기에 그런가보다 
2) ./docker_test 라는 폴더를 만들고 거기에 Dockerfile을 만든다음에 node:8.7.0 을 베이스로 이미지를 만들어봤다.
- ./docker_test 폴더로 server.js 파일 복사했고
- 빌드시에 폴더를 명시했다
 
실습수 docker images --all 로 이미지들을 살펴보았다
![shed-zephy r- 
—al 
R+CSITCAV 
gcr io/gcp_test2/he 0-node 
I qa321 : 
$ docker images 
gcr io/po shed-zephyr-17æ21 'hel 
gcr io/gcp_test/hel lo-node 
lo-node 
mone> 
VI 
mone> 
VI 
VI 
mone> 
mone> 
B. 7.0 
a.g.2 
b01aceab93æ 
Il f6fdld14C8 
1274bd3JeaeO 
faaadb4aaf% 
TED 
7 minutes ago 
7 minutes ago 
B minutes ago 
Z] minutes ago 
Z] minutes ago 
Z] minutes ago 
Z] minutes ago 
g days ago 
10 months ago](GSP-005%20Hello%20Kubernetes.files/image014.jpg)
 
 
| 
   
    | 
  
   docker ps 라고 치면 컨테이너 정보들이 나온다   | 
 
| 
   
    | 
  
   - docker stop <CONTAINER
  ID> 를 치면 멈춘다 - 리턴값은 컨테이너 아이디이다    | 
 
 
 
Google Container Registry https://cloud.google.com/container-registry/
- 도커 이미지를 저장해두는
개인 공간이다. 
- 따라서 개인의 Project 에서 접근이 가능하다 
 
집어넣기 
 
![]()
 
몇 분 걸리며
아래와 같이 나온다
| 
   The push refers to a repository [gcr.io/qwiklabs-gcp-6h281a111f098/hello-node] ba6ca48af64e: Pushed  381c97ba7dc3: Pushed  604c78617f34: Pushed  fa18e5ffd316: Pushed  0a5e2b2ddeaa: Pushed  53c779688d06: Pushed  60a0858edcd5: Pushed  b6ca02dfe5e6: Pushed  v1: digest: sha256:8a9349a355c8e06a48a1e8906652b9259bba6d594097f115060acca8e3e941a2 size: 2002  | 
  
      | 
 
 
웹콘솔의 Tools >> Container Registry 에서 볼 수 있다.
- 퀵랩실습과 내계정으로
한 실습이 섞여 캡처했으니 프로젝트명 바뀌는건 양해를
![Google Cloud Platform 
Container Registry 
Images 
guild triggers 
guild history 
My Project • 
Images 
C REFRESH 
gcrio / polished-zephyr-176321 / hello-node 
Filter by name or tag 
Name 
[ ] 3d04e6C41494 
Tags 
VI](GSP-005%20Hello%20Kubernetes.files/image022.jpg)
 
 
이제 프로젝트
어디에서나 접근이 가능한 도커 이미지가 준비되었다. 
= Kubernetes 가
접근해서 오케스트레이션 가능하다!
 
현재까지
- node.js 서버하나
만들어서 돌려봤고
- Dockerfile을
만들어 도커 이미지를 build한다음에 Google Container
Registry에 집어넣었다. 

 
 
 
Container Engine cluster 를 만들자
- Cluster = Kubernetes master API + worker nodes
- Kubernetes master API는 구글이 hosting 해준다
- worker nodes = Compute Engine VM 이다. 
 
웹콘솔에서
만들수도 있고, Google Cloud Shell 에서 만들수도 있다.
 
Container Engine > Container Clusters > Create a container
cluster.
 
 
1) 프로젝트 설정 제대로
했나 확인
gcloud config set project PROJECT_ID
![]()
 
2) 클러스터 생성
| 
   
    | 
  
   1) hello-world 라는 클러스터를 만들라 2) 노드는 두 개다. = VM 두개
  만든다? 3) VM의 타입은
  n1-standard-1 이고 4) zone 은 us-central1-f
  이다  | 
 
 
웹콘솔의 Container Engine에 가보면 생성된 것을 확인할 수 있다
 
1) 내 프로그램 server.js 를 container image 로 만들어서 container registry 에 넣어두었다.
- 아래 빨간색
2) Kubernetes cluster를 만들었다.
- 아래 파란색
 
 

 
이제 kubectl 이라는 CLI 로 이미지를 클러스터에 올려보자
 
 
- container 들을
하나의 그룹으로 묶은 것이다. 
- Administration = 관리 하려고
- Networking = 내부에서
서로 통신하려고
| 
   
    | 
  
   - hello-node 라는 이름으로 deploy 하라 - 사용할 이미지는 container Registry 의 hello-node:v1 이고 - 포트는 8080 이다 * 여기서 hello-node 라는 이름은 좀 헷갈린다. hello-node-deployment 는 어떨까? * 궁금증. Kubernetes cluster 인 hello-world 는
  언급 안했는데 괜찮나?  자동으로 알아서 현재 클러스터를 안다?
  그렇다면 클러스터 여러 개라면?  | 
 
 
궁금증
때문에 두개의 cluster를 만들어보았다
- 두 개중에
두번째 클러스터랑 붙더라
![gc loud container clusters create hel 10-0 luster —num-nodes 2 -Hnachine-type nl-standard-l 
Creat ing cluster hello-cluster. 
Created [ht tps://contai ner.googleapis.com/vl/proj ects/pol ished-zephyr-l T.æl/zones/us-central I-f/cl usters/hel 
10-0 luster]. 
kubeconfig entry generated for hello-cluster. 
ZONE 
hel 10-0 luster us-central I-f 
MASTEPLVEFSION MASTEPLIP 
MAHNE_TVFE NCOE_VEFSION STATLS 
as. 193.114.73 nl-standard-l 
1.7.a 
gcloud container clusters create hel lo-cluster2 —num-nodes 2 —mach ine-type n I-standard-I 
—zone us-cent ral I -f 
-zone us-central I-f 
Creat ing cluster hello-cluster2.. .done. 
Created [https://container.googleapis.com/vl/proj ects/pol 
kubeconfig entry generated for hello-cluster2. 
ished-zephyr-1 7Eæl / zones/us-central I-f/cl usters/hel lo-c luster?] 
za•4E 
hel lo-cluster2 us-cent rall-f 
MASTdR_VdRSICN MASTdR_IP 
E.2æ.76. 
MACHI NE_TVPE 
241 n I-standard-I 
NOCE-_VBRSICN NUM_NOCES STATUS 
1.7.a](GSP-005%20Hello%20Kubernetes.files/image034.jpg)
 
웹콘솔에서
확인

 
 
deployment 는 pod를 만들고 scale 하는 좋은 방법이다 
* 참고 node는 하나의 컴퓨터 = VM 이라고 보면된다. 하나의 컴퓨터 = VM 안에 여러 개의 컨테이너가 돌 수 있다.
 
| 
   
 
    | 
  
   deploy 한 것들 보는 방법 deploy 가 pod의 상위개념!  | 
 
| 
   
 
    | 
  
   pod 들을 보는 방법  | 
 
| 
   
    | 
  
   관련 정보 보는 명령  | 
 
| 
   
    | 
  
   tourbleshooting 명령  | 
 
 
 
pod를 만들었는데 이건
아직 internal IP로만 접근할 수 있다. =
Kubernetes virtual network
이걸 바깥에서
접근하려면 Kubernetes service 로 pod를 expose 해줘야 한다 
 
![]()
 
 
주의
1) 우리는 deployment 를 expose 했지 pod을 바로 expose 한 것이 아니다
2) 무얼 의미하냐면 deployment 가 pod 들로가는 traffic 을 챙긴다는 것이다
- 현재야 pod가 하나뿐이긴 하다만, 이후 몇 개의 복제 pod를 더 추가할거다
 
| 
   
   
    | 
  
   1) kubectl get services 명령으로 볼 수 있다   2) 위에거만 외부에 노출된 것을 알 수 있다 - AGE를 보면 위에거는
  방금 명령으로 생겨난 것이라 1m 밖에 안된다.    *  The EXTERNAL-IP may take several minutes to
  become available and visible.  If the EXTERNAL-IP is missing,
  wait a few minutes and try again.  | 
 
 
현재까지 정리
- 우리 앱을 컨테이너에
집어넣고, 쿠베르네티스로 관리하는 거 까지 봤다.
- 또 뭘 할 수 있을까?
 
초록색 kubectl 명령으로
- run 명령으로 registry의 이미지를 불러와서 Cluster에 집어넣었고
- expose 명령으로 EXTERNAL-IP를 생성했다. 이때 deployment를 만들때 명시한 8080포트를 이용해야만 볼 수
있다는 것 잊지말자

 
 
| 
   
    | 
  
   app을 스케일 업 하고 싶다면? 이렇게만 명령주면 4개로 복제된다  | 
 
| 
   
 
    | 
  
   deployments 정보  | 
 
| 
   
 
    | 
  
   1개 이던게 총 4개의 pod 가 되어버림  | 
 
 
- 클러스터 생성시에 2개의 노드(=VM)를 가지겠다고 했고
- 그런 클러스터를 테스트삼아
두개 만든거다 
- Scale 전후의 노드
개수는 변동이 없다. 
- 노드(=VM) 안에 여러 개의 Pods (= 컨테이너라고 할까?)가 들어갈 수 있기 때문이다.

 
- 두 번째 만든 클러스터에 deploy 되었구나

 
| 
   
    | 
  
   1) Cloud Shell 에서 kubectl 로 Kubernetes Cluster로 명령 보낼 수 있다.   2) 다양한 device에서 External IP를 통해서 연결이 들어온다 - 123.45.678.9:8080 - Hello Service 에서 노드들에 나눠준다    궁금증 - node #1, node #2 와 그 안의 Hello Node Pod 간의 상관관계는 ? - 노드는 진짜 하나의
  컴퓨터 개념 = VM 이라면 - Pods는 하나의
  컴터안에서 도는 컨테이너 개수라고 할까? - Replication controller 는?  | 
 
 
 
여기까지 우리의 service.js 를 서비스하게 되었다.
그런데 service.js 를 bugfix하고,  feature를 추가하고, refactoring 한다면?
- 업그레이드 하는 방법을
알아보자
 
1. 일단 앱을 수정한다
![]()
 
2. 수정한 앱으로 새로운 container image를 만들고, registry에 밀어넣는다 (v2로 버전업 명시)
 
| 
   
  | 
  
   1) . 은 현재폴더. 현재폴더에
  있는 Dockerfile에 기반하여 이미지를 만들라는 것 2) 만든 이미지를
  registry에 push  | 
 
 
 
replication controller 만 수정하면 된다
 

 
 
kube edit 명령만 치면 된다 
 
![]()
 
| 
   # Please edit the object below. Lines beginning with a '#' will be ignored, # and an empty file will abort the edit. If an error occurs while saving this file will be # reopened with the relevant failures. # apiVersion: extensions/v1beta1 kind: Deployment metadata:   annotations:     deployment.kubernetes.io/revision: "1"   creationTimestamp: 2016-03-24T17:55:28Z   generation: 3   labels:     run: hello-node   name: hello-node   namespace: default   resourceVersion: "151017"   selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/hello-node   uid: 981fe302-f1e9-11e5-9a78-42010af00005 spec:   replicas: 4   selector:     matchLabels:       run: hello-node   strategy:     rollingUpdate:       maxSurge: 1       maxUnavailable: 1     type: RollingUpdate   template:     metadata:       creationTimestamp: null       labels:         run: hello-node     spec:       containers:       - image: gcr.io/PROJECT_ID/hello-node:v1 ## Update this line ##         imagePullPolicy: IfNotPresent         name: hello-node         ports:         - containerPort: 8080           protocol: TCP         resources: {}         terminationMessagePath: /dev/termination-log       dnsPolicy: ClusterFirst       restartPolicy: Always       securityContext: {}       terminationGracePeriodSeconds: 30  | 
  
 
 
4. 변경된
것으로 다시 돌리기
 
get 명령이지만
이걸 해줘야 deployment 가 update 된다. 
실제 사용자는
어떤 인터럽트도 느끼지 않고 자연스럽게 버전업을 사용할 수 잇게 된다 
 

 
 
 
Kubernetes cluster dashboard 를 접근하기 위한 설정
- 참고로 여기서 hello-world 는 클러스터 이름임

 
그리고 8081로 접근하면 된다 

 
 
 
- 음… 그런데 해보는데
안된다. 
- https://github.com/kubernetes/kubernetes/issues/52729

 

 
 
 
1) 일단 프록시 포트
설정
![]()
 
2) 내 컴퓨터의 브라우저를
열고 127.0.0.1:8081 을 열면
아래와 같이 나온ㄷ

 
3) 원래는 여기에 ui 만 붙인 https://goo.gl/dT99Hm
만 치면 
http://127.0.0.1:8081/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy
로
redirection 되면서 되어야 한다. 
 
그런데 이 url 은 틀렸다. 정답은 아래!
| 
   - 맨 끝에 /를 넣어주거나  http://127.0.0.1:8081/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy/ - proxy 단어 위치를
  namepaces 앞으로 옮기고 맨 끝에 /를 넣어주면 된다. http://127.0.0.1:8081/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/  | 
 
 
 
노드의 key/value 쌍인 labels 참고
 
- service의 LoadBalancer는 이 라벨로 노드들에 명령을 보낼 수 있다. 
- 같은 라벨의 노드가 3개라면? 3개에 동시에 보내는 거다
- 또 다른 라벨로 명령을
보내느데 그건 또 다른 쌍으로 5개의 노드를 가리킨다면? 그 5개에만 보내는거다

 
 
Microsoft OneNote 2016에서 작성